/*
  Copyright (C) 2011 by the PSVN Research Group, University of Alberta
*/

#include "astar_data.hpp"

void AStarData::Clear()
{
    m_data.Clear();
    m_open.Clear();
}

bool AStarData::Relax(int64_t hash, const int g, const void* parent)
{
    StateData* ptr = m_data.GetPointer(hash);
    if (ptr == NULL)
        return false;
    if (g >= ptr->m_g)
        return true;
    assert(ptr->m_expanded == false);
    RemoveFromOpen(ptr->m_g + ptr->m_h, ptr->m_g, ptr->m_index);
    ptr->m_g = g;
    ptr->m_came_from = parent;
    ptr->m_index = AddToOpen(hash, ptr->m_g + ptr->m_h, ptr->m_g);
    return true;
}

bool AStarData::OpenListEmpty()
{
    // pop any stale arrivals before determining if list is empty
    while (!m_open.Empty()) {
        int64_t hash = m_open.Top();
        if (hash != 0) // not stale!
            break;
        m_open.Pop();
    }
    return m_open.Empty();
}

void AStarData::Pop(int64_t& hash, StateData& data)
{
    assert(!m_open.Empty());
    hash = m_open.Top();
    m_open.Pop();
    StateData* ptr = m_data.GetPointer(hash);
    assert(ptr != NULL);
    ptr->m_index = -1;   // mark that it is no longer in open list
    ptr->m_expanded++;
    data = *ptr;
}
